package com.ys.controller.api.logistics;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ys.config.MenuId;
import com.ys.entity.logistics.TlCustomsDeclaration;
import com.ys.entity.logistics.TlDecCustomSub;
import com.ys.entity.sys.YsCol;
import com.ys.service.flow.YspTaskService;
import com.ys.service.logistics.TlCustomsDeclarationService;
import com.ys.service.sys.CommonApiService;
import com.ys.service.sys.UploadService;
import com.ys.util.ExportExcelUtils;
import com.ys.util.admin.ConditionUtil;
import com.ys.util.shiro.ShiroUtils;
import com.ys.vo.LayuiTableVoJA;
import com.ys.vo.R;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 报关单
 */
@Controller
@RequestMapping("/api/inter/tlCustomsDeclaration")
public class ApiInterTlCustomsDeclarationController {
    private static final Logger logger = LoggerFactory.getLogger(ApiInterTlCustomsDeclarationController.class);

    @Autowired
    private CommonApiService<TlCustomsDeclaration> commonApiService;

    @Autowired
    private CommonApiService<TlDecCustomSub> commonApiServiceByTlDecCustomSub;

    @Autowired
    private TlCustomsDeclarationService tlCustomsDeclarationService;

    //菜单id
    private Long menuId = MenuId.TL_CustomsDeclaration;

    //权限字符
    private final String PERMISSIONS_VIEW = "tlCustomsDeclaration:view";
    private final String PERMISSIONS_ADD = "tlCustomsDeclaration:add";

    /**
     * 设置查询的cond的sql设置
     * @param cond
     * @return
     */
    public TlCustomsDeclaration setSeachSql(TlCustomsDeclaration cond){

        cond
                .addLeftJoin("TS_UserChange U ON U.Id = A.CreateChangeId ")
                .addField("U.UserId + '/' + U.UserName AS _ys_createUserName")//制单人
                .addField("U.UserId AS userId")

                .addLeftJoin("YS_ProcInst P ON P.Bid = A.Bid ")
                .addField("FORMAT(P.UpdateTime, 'yyyy-MM-dd HH:mm:ss') AS auditingTime")//审核时间

                .addLeftJoin("TL_CustomsDeclarationItem S ON S.Pbid = A.Bid ")//子表
                .addField("S.CustomsQuantity AS customsQuantity")//本次报关数量

                .addLeftJoin("TL_DecCustomSub DS ON DS.Id = S.DecCustomSubId ")//报关子件表

                .addLeftJoin("TCG_PurchaseAppointOrderProductComponent PAC ON PAC.Id = DS.ComponentId")//预约采购管理子件表
                .addField("PAC.SubCode AS subCode")//子件编码
                .addField("PAC.SubName AS subName")//子件名称
                .addField("PAC.SubCodeMerge AS subCodeMerge")//子件合并编码

                .addLeftJoin("TCG_PurchaseContractItem PCI ON PCI.OrderProductComponentId = PAC.Id ")//采购合同管理子表
                .addLeftJoin("TCG_PurchaseContract PCIP ON PCIP.Bid = PCI.Pbid ")//采购合同管理
                .addLeftJoin("TB_CompanyInfo C ON C.Vid = PCIP.CompanyInfoVid ")//公司信息表
                .addField("C.Vname AS vname")//购买方公司名称

                .addLeftJoin("TCW_PartnerBankInfo PBI ON PBI.Id = PCIP.PartnerBankInfoId ")//合作商银行账户管理
                .addField("PBI.PartnerName AS partnerName")//供应方公司名称


                .addLeftJoin("TL_CustomsDeclarationInvoice SI ON SI.Pid = S.Id ")//发票扣减信息表
                .addField("SI.DeductQuantity AS deductQuantity")//发票扣减数量
                .addField("SI.DeductBeforeQuantity AS deductBeforeQuantity")//发票扣减前数量(发票可报关数量)
                .addField("SI.DeductQuantityByNo AS deductQuantityByNo")//报关未扣减数量
                .addField("SI.NumDecCustomByInvoice AS numDecCustomByInvoice")//发票已报关数量
                .addField("SI.InvoiceSurplusNum AS invoiceSurplusNum")//发票剩余数量
                .addField("SI.DeductQuantityByAfter AS deductQuantityByAfter")//报关扣减后数量

                .addLeftJoin("TCG_InvoiceOffsetItem IOS ON IOS.Id = SI.InvoiceOffsetItemId ")//发票管理子表
                .addField("IOS.InvoiceModelNo AS invoiceModelNo")//发票型号
                .addField("IOS.InvoiceName AS invoiceName")//发票品名
                .addField("IOS.OffsetNum - IOS.CustomsNum AS invoiceSurplusNumByInvoice")//发票剩余报关数量
                .addField("IOS.OffsetNum AS offsetNum")//发票数量

                .addLeftJoin("TCG_InvoiceOffset I ON I.Bid = IOS.Pbid ")//发票管理
                .addField("I.SourceAddress AS sourceAddress")//货源所在地

                .addLeftJoin("TCG_InvoiceRegist IR ON IR.InvoiceOffsetId = I.Id AND IR.EffectStock = 1")//发票登记单
                .addField("IR.InvoiceNo AS invoiceNo")//发票号码



        //排序
        .setOrderby("A.Bid DESC");

        cond = commonApiService.dataAuth(menuId, cond);
        return  cond;
    }


    /**
     * 查询
     */
    @RequiresPermissions(PERMISSIONS_VIEW)
    @RequestMapping("/search")
    @ResponseBody
    public LayuiTableVoJA search(@ModelAttribute TlCustomsDeclaration cond,String conditions
    ){
        try {
            cond = setSeachSql(cond);
            //查询条件
            String nameLinked = ConditionUtil.getConditionValue(conditions, "_ys_createUserName");//制单人
            if (nameLinked != null){
                cond.where("U.UserId LIKE '%" + nameLinked + "%'" + " OR  U.UserName LIKE '%" + nameLinked + "%'");
            }
            LayuiTableVoJA setList = commonApiService.searchLay(cond);

            return setList;
        }catch (Exception e){
            logger.error("查询出错：",e.getMessage(),e);
            LayuiTableVoJA tableVoJA = new LayuiTableVoJA();
            tableVoJA.setCode(1);
            tableVoJA.setMsg("查询出错，请稍后重试！");
            return tableVoJA;
        }
    }


    /**
     * 导出
     */
    @RequestMapping("/export")
    @ResponseBody
    public R export(@ModelAttribute TlCustomsDeclaration cond,String conditions){
        try {
            cond.setPage(0).setSize(999999);
            cond = setSeachSql(cond);
            //查询条件
            String nameLinked = ConditionUtil.getConditionValue(conditions, "_ys_createUserName");//制单人
            if (nameLinked != null){
                cond.where("U.UserId LIKE '%" + nameLinked + "%'" + " OR  U.UserName LIKE '%" + nameLinked + "%'");
            }
            //获取菜单字段数据
            List<YsCol> listField = new YsCol()
                    .setMenuId(menuId)
                    .setFrontShow(1)
                    .setOrderby("A.SortNo asc")
                    .queryList();
            //获取数据
            List<Map<String, Object>> listData = cond.queryMap();

            //处理数据
            ExportExcelUtils<TlCustomsDeclaration> util = new ExportExcelUtils<>(new TlCustomsDeclaration());
            String toFilePath = util.exportExcel(listData, listField, "报关单");
            UploadService.UploadDto dto = commonApiService.uploadLocalToServer(toFilePath);
            return R.ok(dto.getUrl());
        }catch (Exception e){
            logger.error("导出出错：",e.getMessage(),e);
            return R.error("导出失败，请稍后重试！");
        }
    }



    /**
     * 新增
     */
    @RequiresPermissions(PERMISSIONS_ADD)
    @RequestMapping("/toAdd")
    @ResponseBody
    public R toSave(HttpServletRequest request, @RequestParam Map<String, Object> params){
        try {
            //新增
            return tlCustomsDeclarationService.add(params,menuId);
        } catch (IllegalArgumentException e) {
            logger.error("出错：",e.getMessage(),e);
            return R.error(e.getMessage());
        } catch (Exception e) {
            logger.error("新增出错：",e.getMessage(),e);
            return R.error(e.getCause().getMessage());
        }
    }


    /**
     * 修改
     */
    @RequiresPermissions(PERMISSIONS_ADD)
    @RequestMapping("/toEdit")
    @ResponseBody
    public R toEdit(HttpServletRequest request, @RequestParam Map<String, Object> params){
        try {
            //修改
            return tlCustomsDeclarationService.update(params,menuId);
        } catch (IllegalArgumentException e) {
            logger.error("出错：",e.getMessage(),e);
            return R.error(e.getMessage());
        } catch (Exception e) {
            logger.error("修改出错：",e.getMessage(),e);
            return R.error(e.getCause().getMessage());
        }
    }


    /**
     * 删除
     */
    @RequiresPermissions(PERMISSIONS_ADD)
    @PostMapping("/toDel")
    @ResponseBody
    public R toDel(Long id){
        try {
            return tlCustomsDeclarationService.del(id);
        } catch (IllegalArgumentException e) {
            logger.error("出错：",e.getMessage(),e);
            return R.error(e.getMessage());
        } catch (Exception e) {
            logger.error("出错：",e.getMessage(),e);
            return R.error(e.getCause().getMessage());
        }
    }


    /**
     * 流转通过
     */
    @RequiresPermissions(PERMISSIONS_ADD)
    @PostMapping("/flowPass")
    @ResponseBody
    public R flowPass(HttpServletRequest request, Long id){
        try {
            return tlCustomsDeclarationService.flowPass(id,ShiroUtils.getUserId());
        } catch (IllegalArgumentException e) {
            logger.error("出错：",e.getMessage(),e);
            return R.error(e.getMessage());
        } catch (Exception e) {
            logger.error("出错：",e.getMessage(),e);
            return R.error(e.getCause().getMessage());
        }
    }

    /**
     * 流转退回
     */
    @RequiresPermissions(PERMISSIONS_ADD)
    @PostMapping("/flowRefuse")
    @ResponseBody
    public R flowRefuse(HttpServletRequest request, Long id, String reason){
        try {
            TlCustomsDeclaration entity = new TlCustomsDeclaration().setId(id).queryFirst();
            return tlCustomsDeclarationService.flowRefuse(entity.getBid(), reason,ShiroUtils.getUserId());
        } catch (IllegalArgumentException e) {
            logger.error("出错：",e.getMessage(),e);
            return R.error(e.getMessage());
        } catch (Exception e) {
            logger.error("出错：",e.getMessage(),e);
            return R.error(e.getCause().getMessage());
        }
    }


    /**
     * 流转驳回
     */
    @RequiresPermissions(PERMISSIONS_ADD)
    @PostMapping("/flowInit")
    @ResponseBody
    public R flowInit(HttpServletRequest request, Long id, String reason){
        try {
            TlCustomsDeclaration entity = new TlCustomsDeclaration().setId(id).queryFirst();
            return tlCustomsDeclarationService.flowInit(entity.getBid(), reason,ShiroUtils.getUserId());
        } catch (IllegalArgumentException e) {
            logger.error("出错：",e.getMessage(),e);
            return R.error(e.getMessage());
        } catch (Exception e) {
            logger.error("出错：",e.getMessage(),e);
            return R.error(e.getCause().getMessage());
        }
    }



    /**
     * 打印
     */
    @RequiresPermissions(PERMISSIONS_ADD)
    @PostMapping("/doPrint")
    @ResponseBody
    public R doPrint(HttpServletRequest request, String bid){
        try {
            return tlCustomsDeclarationService.doPrint(bid);
        } catch (Exception e) {
            logger.error("出错：",e.getMessage(),e);
            return R.error(e.getCause().getMessage());
        }
    }


    /**
     * 根据子列表信息，获取对应发票扣减列表信息
     */
    @RequiresPermissions(PERMISSIONS_ADD)
    @PostMapping("/getInvoiceDeductionAddInvoice")
    @ResponseBody
    public JSONObject getInvoiceDeductionAddInvoice(HttpServletRequest request, @RequestParam Map<String, Object> params){
        JSONObject res = new JSONObject();
        try {
            JSONArray subDataArray = JSON.parseArray(params.get("subData").toString());
            List<Map<String, Object>> subDataList = new ArrayList<>();
            for (int i = 0; i < subDataArray.size(); i++) {
                JSONObject jsonObject = subDataArray.getJSONObject(i);
                Map<String, Object> paramsNewByRecord = new HashMap<>();
                for (String key : jsonObject.keySet()) {
                    paramsNewByRecord.put(key, jsonObject.get(key));
                }
                subDataList.add(paramsNewByRecord);
            }
            List<Map<String, Object>> resList = tlCustomsDeclarationService.getInvoiceDeductionAddInvoice(subDataList);
            res.put("resList",resList);
            res.put("code",R.Code.SUCCESS.value);
            return res;
        } catch (Exception e) {
            logger.error("出错：",e.getMessage(),e);
            res.put("code",R.Code.FAILED.value);
            return res;
        }
    }



    /**
     * 报关信息管理（报关单调用）
     */
    @RequestMapping("/modalByCustomsDeclaration")
    @ResponseBody
    public LayuiTableVoJA modalByCustomsDeclaration(com.bo.annotation.Model model, HttpServletRequest request, HttpServletResponse response,
                                                      @ModelAttribute TlDecCustomSub cond, String conditions) {
        cond
                //.addLeftJoin("TL_DecCustomSub DS ON DS.Id = A.DecCustomSubId ")//报关子件表
                //.addField("A.NumDecCustom AS numDecCustom")//已报关数量
                .addField("A.Id AS decCustomSubId")//报关信息子件表id

                .addField(" CONVERT(VARCHAR(255), A.Id) + DBP.BoxCode + FLD.Guid  AS onlyOneKey")//唯一值 = 报关信息子件表id + 装箱号 + 物流订单详情表guid

                .addLeftJoin("TL_DecCustomBoxProduct DBP ON A.DecCustomBoxProductId = DBP.Id ")//所属箱子产品表
                .addField("DBP.Num AS num")//母件装箱数量
                .addField("DBP.Pbid AS decCustomBid")//报关单号
                .addField("DBP.BoxCode AS boxCode")//装箱号

                .addLeftJoin("TL_DecCustom DC ON DC.Bid = DBP.Pbid ")//报关信息表
                .addField("DC.FbaLogsticsOrderId AS fbaLogsticsOrderId")//物流订单表id

                //.addLeftJoin("(SELECT DCBS.BidFbaBox,DCBS.Pbid FROM TL_DecCustomBox DCBS GROUP BY DCBS.BidFbaBox,DCBS.Pbid ) DCB ON DC.Bid = DCB.Pbid ")//报关信息装箱表
                .addLeftJoin("TL_DecCustomBox DCB ON DBP.BoxCode = DCB.BoxCode ")//报关信息装箱表
                .addField("DCB.BidFbaBox AS bidFbaBox")//装箱单号
                .addField("DCB.BoxIndex AS boxIndex")//箱号

                .addLeftJoin("TP_FbaLogsticsOrder FL ON FL.Id = DC.FbaLogsticsOrderId ")//物流订单表
                .addField("FL.Code AS fbaLogsticsOrderCode")//物流订单号
                .addField("FL.WaybillNumber AS waybillNumber")//物流运单号
                .addField("FL.DestinationFulfillmentCenterId AS destinationFulfillmentCenterId")//仓库标识
                .addField("FL.NameLogsticsWay AS pNameLogsticsWay")//物流名称
                .addField("FL.CodeLogsticsServer AS codeLogsticsServer")//物流服务商

                .addLeftJoin("TP_FbaLogsticsOrderDetail FLD ON FLD.CodeFbaLogsticsOrder = FL.Code ")//物流订单详情表
                .where("FLD.Bid = DCB.BidFbaBox")
                .addField("FLD.Guid AS fbaLogsticsOrderDetailGuid")//物流订单详情表guid
                //.addInnerJoin("TP_FbaLogsticsOrderDetail FLD ON FLD.CodeFbaLogsticsOrder = FL.Code AND FLD.Bid = DCB.BidFbaBox")//物流订单详情表
                .addField("FLD.ShipmentId AS shipmentId")//FBA编号
                .addField("FLD.TrackingCode AS trackingCode")//货件追踪编号
                .addField("FLD.NameLogsticsWay AS nameLogsticsWay")//物流方式
                .addField("FLD.Code AS fbaLogsticsOrderDetailCode")//头程装箱单

                //.addField("FLD.CountryCode AS countryCode")//目的地国家简称

                .addLeftJoin("TP_AmazonAddress AAD ON AAD.DestinationFulfillmentCenterId = FL.DestinationFulfillmentCenterId ")//亚马逊仓库地址管理表
                .addField("AAD.CountryCode AS countryCode")//目的地国家简称

                .addLeftJoin("TP_FbaShipment FS ON FS.Code = FLD.CodeShipment ")//头程货件单
                .addField("FS.CodePlan AS codePlan")//头程计划单号

                .addLeftJoin("TCG_PurchaseAppointOrderProductComponent PAC ON PAC.Id = A.ComponentId")//预约采购管理子件表
                .addField("PAC.SubCode AS subCode")//子件编码
                .addField("PAC.SubName AS subName")//子件名称
                .addField("PAC.SubCodeMerge AS subCodeMerge")//子件合并编码

                .addLeftJoin("TCG_PurchaseAppointOrderItem PAOI ON PAOI.Id = PAC.Pid")//预约采购管理母件表
                .addField("PAOI.ProductCode AS productCode")//商品编码
                .addField("PAOI.ProductName AS productName")//商品名称

                .addLeftJoin("TCG_PurchaseContractItem PCI ON PCI.OrderProductComponentId = PAC.Id ")//采购合同管理子表
                .addField("PCI.SubBomNumber AS subBomNumber")//子件BOM数量
                .addField("PCI.SubPurchaseNum AS subPurchaseNum")//子件采购数量
                .addField("PCI.SubPurchasePrice AS subPurchasePrice")//子件采购单价

                .addLeftJoin("TP_ProductActiveComponent CS ON CS.Code = PAC.SubCode ")//listing库子件表
                .addField("CS.CustomsCode AS customsCode")//海关编码
                .addField("CS.ExemptionTax AS exemptionTax")//征免
                .addField("CS.CustomsExplain AS customsExplain")//商品报关说明
                .addField("CS.CountryName AS countryName")//原产国（地区）
                .addField("CS.SingleWeight AS singleWeight")//商品单重
                .addField("CS.InvoiceModelNo AS invoiceModelNo")//发票型号
                .addField("CS.InvoiceName AS invoiceName")//发票品名

                .addField("DBP.Num * PCI.SubBomNumber AS subBoxNum")//子件装箱数量 = 母件装箱数量*子件BOM数量


                .addLeftJoin("TCG_PurchaseContract PCIP ON PCIP.Bid = PCI.Pbid ")//采购合同管理
                .addLeftJoin("TB_CompanyInfo C ON C.Vid = PCIP.CompanyInfoVid ")//公司信息表
                .addField("C.Vname AS vname")//购买方公司名称

                .addLeftJoin("TCW_PartnerBankInfo PBI ON PBI.Id = PCIP.PartnerBankInfoId ")//合作商银行账户管理
                .addField("PBI.PartnerName AS partnerName")//供应方公司名称

                /*
                .addLeftJoin("TCG_InvoiceOffsetItem IOS ON IOS.PurchaseContractItemId = PCI.Id ")//发票管理子表

                .addField("IOS.Id AS invoiceOffsetItemId")//发票管理子表id
                .addField("IOS.InvoiceModelNo AS invoiceModelNo")//发票型号
                .addField("IOS.InvoiceName AS invoiceName")//发票品名
                .addField("IOS.OffsetNum - IOS.CustomsNum AS invoiceSurplusNum")//发票剩余报关数量

                .addLeftJoin("TCG_InvoiceOffset I ON I.Bid = IOS.Pbid ")//发票管理
                .addField("I.SourceAddress AS sourceAddress")//货源所在地

                .addLeftJoin("TCG_InvoiceRegist IR ON IR.InvoiceOffsetId = I.Id")//发票登记单
                .addField("IR.InvoiceNo AS invoiceNo")//发票号码

                .where("IR.EffectStock = 1")//审批通过的
                .where("IOS.CustomsState !=1")//报关完整性(0否、1是)

                 */




                .setStatus(1)

        ;


        LayuiTableVoJA tableVoJA = commonApiServiceByTlDecCustomSub.searchLay(cond);
        return tableVoJA;

    }







}